#include "TcpServer.hpp"
#include <memory>

using namespace tcp_server;

void Usage(const std::string &proc)
{
    std::cerr << "Usage:\n\t" << proc << " port" << std::endl;
}

bool cal(const Request &req, Response &resp)
{
    // 只进行逻辑处理而不考虑其他的任何读写等——解耦

    // 走到这，请求已经是结构化的了
    switch (req._op)
    {
    case '+':
        resp._result = req._x + req._y;
        break;
    case '-':
        resp._result = req._x - req._y;
        break;
    case '*':
        resp._result = req._x * req._y;
        break;
    case '/':
        if (req._y == 0)
            resp._exitcode = DIV_ZERO;
        else
            resp._result = req._x / req._y;
        break;
    case '%':
        if (req._y == 0)
            resp._exitcode = MOD_ZERO;
        else
            resp._result = req._x % req._y;
        break;
    default:
        resp._exitcode = OP_ERROR;
        break;
    }

    return true;
}

void calculate(Connection *conn)
{
    logMessage(DEBUG, "calculate start");
    /* 解析数据，得到完整报文 */
    std::string one_package;
    while (ParseOnePackage(conn->_inbuffer, &one_package))
    {
        // 走到这里，得到一个完整报文

        // 解析报文，得到有效载荷
        std::string req_str;
        if (!DeLength(one_package, &req_str))
        {
            logMessage(DEBUG, "从报文中解析正文失败");
            return; // 解析失败
        }
        std::cout << "去掉报头的正文：\n"
                  << req_str << std::endl;

        // 对请求正文做反序列化
        Request req;
        if (!req.deserialize(req_str))
        {
            logMessage(DEBUG, "请求正文反序列化失败");
            return; // 反序列化失败
        }

        // 构建响应
        Response resp;
        cal(req, resp);

        // 对响应做序列化
        std::string resp_str;
        resp.serialize(&resp_str);
        // 添加报头，构建完整的报文，添加到发送缓冲区
        conn->_outbuffer = EnLength(resp_str);

        std::cout << "完整响应报文: \n"
                  << conn->_outbuffer << std::endl;
    }

    // 回送
    if (conn->_sender)
        conn->_sender(conn); // 直接发送

    // // 没有发送完毕，就要对对应的socket开启对写事件的关心
    // if (!conn->_outbuffer.empty())
    //     conn->_tsp->EnableReadWrite(conn, true, true);
    // // 发送完毕，就要关闭对对应的socket关闭对写事件的关心
    // else
    //     conn->_tsp->EnableReadWrite(conn, true, false);

    logMessage(DEBUG, "calculate end");
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(USAGE_ERROR);
    }

    uint16_t port = atoi(argv[1]);
    std::unique_ptr<TcpServer> tsvr(new TcpServer(calculate, port));

    tsvr->InitServer();
    tsvr->Dispatch();

    return 0;
}